﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Newtonsoft.Json;
using Core.Connexions;

namespace Main.Packets
{
    /// <summary>
    /// Paquet de données
    /// </summary>
    public class DataPacket : Packet
    {
        private string data;
        private int nombreRetransmissions;

        private DataPacket(byte numeroConnexion, PacketType type, string data) : base(numeroConnexion, type)
        {
            this.data = data;
            this.nombreRetransmissions = 0;
        }

        #region Propriétés

        [JsonProperty(Order = 15)]
        public string Data
        {
            get { return data; }
            set { data = value; }
        }

        [JsonIgnore]
        public int NombreRetransmission
        {
            get { return nombreRetransmissions; }
        }

        #endregion

        /// <summary>
        /// Incrémente le nombre de retransimissions
        /// </summary>
        public void IncrementerNombreRetransmissions()
        {
            nombreRetransmissions++; 
        }

        /// <summary>
        /// Instanciation d'un ou plusieurs paquets (segmentation) de données à partir des données reçues de la primitive NDATA.REQ
        /// et ajoute les paquets au packets en attente de la connexion passé en paramètre.
        /// </summary>
        public static void CreateDataPackets(ConnexionReseau connexion, string data)
        {
            int length;
            bool hasNext;
            DataPacket packet;

            for (int i = 0; i < data.Length; i += REGLES.MAX_BYTES)
            {
                hasNext = ((i + REGLES.MAX_BYTES) < data.Length);

                length = Math.Min(data.Length - i, REGLES.MAX_BYTES);

                packet = new DataPacket(connexion.IdConnexionLogique, PacketType.CreateTypeForDataPacket(connexion.CurrentPR, hasNext, connexion.NextPS), data.Substring(i, length));

                connexion.AddDataPacketWaiting(packet);
            }
        }

        /// <summary>
        /// Instanciation d'un paquet de données à partir d'une ligne reçue d'une couche supérieure ou inférieure.
        /// </summary>
        public static DataPacket CreateDataPacket(string str)
        {
            return JsonConvert.DeserializeObject<DataPacket>(str) as DataPacket;
        }

        /// <summary>
        /// Envoie d'un paquet de données vers le flux passé en paramètre.
        /// </summary>
        public override void Send(System.IO.StreamWriter sw)
        {
            sw.WriteLine(JsonConvert.SerializeObject(this));
        }

        public override string ToString()
        {
            return base.ToString() + "Donnees : " + this.data;
        }
    }
}
